<?php

namespace App\Api\Services;

use App\Api\Contracts\VerifyReqContract;
use App\Api\Enums\ResponseEnum;
use App\Api\Exceptions\BusinessException;
use App\Api\Traits\BusinessExceptionTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class VerifyReqService implements VerifyReqContract
{
    use BusinessExceptionTrait;

    public function __construct(public Request $req)
    {

    }

    public function file(string $key): \Illuminate\Http\UploadedFile|array|null
    {
        return $this->req->file($key);
    }

    public function input(string $key): mixed
    {
        return $this->req->input($key);
    }

    public function all(): array
    {
        return $this->req->all();
    }

    /**
     * @param $params
     * @param array $exp
     * @param array $formate
     * @param array $message
     * @return array|void
     * @throws BusinessException
     */
    public function checkParams($params, array $exp = [], array $formate = [], array $message = [])
    {
        $validator_target = [];
        $validator_values = [];
        if ($params)
            foreach ($params as $value) {
                $this->checkParam($value, $validator_target, $validator_values);
            }
        if ($exp)
            foreach ($exp as $value) {
                $this->checkExpParam($value, $validator_target, $validator_values);
            }

        $validator = Validator::make($this->req->all(), $validator_target, $message);
        if (!$validator->fails()) {
            if ($formate)
                foreach ($formate as $key => $value) { // 类似as的功能 key值替换
                    if (isset($validator_values[$key]) && !isset($validator_values[$value])) {
                        $validator_values[$value] = $validator_values[$key];
                        unset($validator_values[$key]);
                    }
                }
            return $validator_values;
        } else {
            $this->throwBusinessException(info: $validator->errors()->first());
        }
    }

    public function getParam($param)
    {
        $validator_target = [];
        $validator_values = [];

        $this->checkParam($param, $validator_target, $validator_values);

        $validator = Validator::make($this->req->all(), $validator_target);

        if (!$validator->fails()) {
            return $validator_values;
        } else {
            $this->throwBusinessException(info: $validator->errors()->first());
        }
    }


    /**
     * @exp 验证必选参数
     * @param $param
     * @param $validator_target
     * @param $validator_values
     */
    public function checkParam($param, &$validator_target, &$validator_values)
    {
        $index = strpos($param, ':');
        if (!empty($index)) {
            $param_name = substr($param, 0, $index); // 获取参数名
            $param_avlid = substr($param, $index + 1); // 获取验证规则
            // 拆分重组
            $validator_target[$param_name] = "required|$param_avlid";

            if ($this->req->has($param_name)) {
                $this->req->hasFile($param_name) ? $validator_values[$param_name] = $this->req->file($param_name) : $validator_values[$param_name] = $this->req->input($param_name);
            }
        } else {
            $validator_target[$param] = "required";
            if ($this->req->has($param)) {
                $this->req->hasFile($param) ? $validator_values[$param] = $this->req->file($param) : $validator_values[$param] = $this->req->input($param);
            }
        }
//        return ['validator_target' => $validator_target, 'validator_values' => $validator_values];
    }

    /**
     * @exp 验证非必选参数
     * @param $param
     * @param $validator_target
     * @param $validator_values
     */
    public function checkExpParam($param, &$validator_target, &$validator_values)
    {
        $index = strpos($param, ':');
        if (!empty($index)) {
            $param_name = substr($param, 0, $index); // 获取参数名

            // 拆分重组
            if ($this->req->has($param_name)&&$this->req->filled($param_name)) {
                $validator_target[$param_name] = substr($param, $index + 1);// 获取验证规则
                $this->req->hasFile($param_name) ? $validator_values[$param_name] = $this->req->file($param_name) : $validator_values[$param_name] = $this->req->input($param_name);
            }
        } else {
            if ($this->req->has($param)&&$this->req->filled($param)) {
                $this->req->hasFile($param) ? $validator_values[$param] = $this->req->file($param) : $validator_values[$param] = $this->req->input($param);
            }
        }
    }

    /**
     * @exp 验证错误信息字符串化
     * @param $err
     * @return mixed
     */
    public function errMsg($err): mixed
    {
        $err = json_decode($err, true);
        foreach ($err as $k => $v) {
            $err[$k] = implode('&', $v);
        }
        return $err;
    }

    public function jsonToErrMsg($result)
    {
        header('Content-Type:application/json');
        exit(json_encode($result));
    }

}
